-- UISkillInfo
-- Created by huanghr
-- 技能学习界面

require "game/ui/form/hero/UILearnNewSkillEffect"

UISkillInfo = class("UISkillInfo", function()
    return cc.Layer:create();
end);

function UISkillInfo.create(careerList)
    return UISkillInfo.new(careerList);
end

-- 最多可显示星星数
local MAX_STAR_NUM = 5;

-- 属性半透明度
local ATTRIB_OPACITY_VALUE = 100;

-- 职业最大阶位
local MAX_RANK = 5;

-- 内部函数声明
local resize;

function UISkillInfo:ctor(careerId)
    -- 初始化
    self:setName("UISkillInfo");
    local node = cc.CSLoader:createNode("layout/hero/SkillLearn.csb");
    self:addChild(node);
    self.node = node;

    local pet = ME.user:getActivePet();
    self.pet = pet;

    self.careerId = careerId;

    -- 需要显示在头部菜单上面
    self:setLocalZOrder(UIMgr.TOP_MENU_ZORDER + 1);

    -- 注册点击事件
    performWithDelay(self, function() self:registerTouchEvent(); end, 0.5);

    -- 初始化窗口
    self:initForm();

    -- 重绘
    self:redraw();

    -- 适配
    resize(node);
end

-- 适配
function resize(node)
    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
end

-- 初始化窗口
function UISkillInfo:initForm()
    local skillPanel = findChildByName(self.node, "CT/skill_panel");
    local panelWidth  = skillPanel:getContentSize().width;
    local panelHeight = skillPanel:getContentSize().height;

    -- 图标间距
    local gap = 90;

    -- 职业个数
    local count = 1;

    -- 图标宽、高
    local iconWidth  = 180;
    local iconHeight = 180;


    local child = cc.CSLoader:createNode("layout/hero/SkillIcon2.csb");
    skillPanel:addChild(child);

    -- 计算图标与容器的边距
    local margin = (panelWidth - (count * iconWidth + (count - 1) * gap))/2;
    local posX =  margin + (1 - 1) * (iconWidth + gap) + iconWidth/2;
    child:setPosition(posX, panelHeight/2);

    local careerInfo = CareerM.getCareerInfo(self.careerId);

    local iconImg   = findChildByName(child, "icon");
    iconImg:setScale(1.2);
    local nameLabel = findChildByName(child, "name");
    local kerning = 0;
    if getLang() ~= "zh" then
        kerning = -2;
    end
    iconImg:loadTexture(getCareerIconPath(careerInfo["icon"]));
    TextStyleM.setTextStyle(nameLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_BRIGHT_YELLOW, true, kerning);
    nameLabel:setString(careerInfo["name"]);
    nameLabel:setVisible(false);

    -- 默认隐藏选中光效
    local light = findChildByName(child, "light");
    light:setVisible(false);

    -- 记录箭头的初始纵坐标
    local arow = findChildByName(child, "arow");
    arow.initPosY = arow:getPositionY();

    -- 初始化特效节点
    local basePropNode = findChildByName(self.node, "CT/base_prop_node");

    -- 攻击
    local effectNode = findChildByName(basePropNode, "attack_node/effect_node");
    playAttribSparkEffect(effectNode, 1133);
    effectNode:setVisible(false);

    -- 生命
    effectNode = findChildByName(basePropNode, "hp_node/effect_node");
    playAttribSparkEffect(effectNode, 1133);
    effectNode:setVisible(false);

    -- 魔力
    effectNode = findChildByName(basePropNode, "magic_node/effect_node");
    playAttribSparkEffect(effectNode, 1133);
    effectNode:setVisible(false);

    -- 魔法
    effectNode = findChildByName(basePropNode, "mp_node/effect_node");
    playAttribSparkEffect(effectNode, 1133);
    effectNode:setVisible(false);
end

-- 重绘
function UISkillInfo:redraw()
    -- 显示标题
    local titleLabel = findChildByName(self.node, "CT/title_node/title");

    local careerInfo = CareerM.getCareerInfo(self.careerId);
    titleLabel:setString(careerInfo["name"]);
    TextStyleM.setArtWordTitleStyle(titleLabel);

    -- 绘制星级
    local starNode = findChildByName(self.node, "CT/title_node/star_node");
    local rank = careerInfo["rank"]
    local starScale = 1;
    local offsetY = 0;
    -- 最大等级需要特殊显示
    local starLayer;
    if rank == MAX_RANK then
        -- 获取已满级的特性数量
       -- local curStar = CareerM.getLevelUpperFeatureNum(self.pet, ids[i]);
        local lightStarPath = "images/ui/symbol/moon_01.png";
        starLayer = createStarLayer(3, lightStarPath);
        starScale = 0.7;
        offsetY = 1;
    else
        local lightStarPath = "images/ui/symbol/star_large.png";
        starLayer = createStarLayer(3, lightStarPath);
    end
    starNode:removeAllChildren();
    starNode:addChild(starLayer);
    starNode:setScale(starScale);
    local x = starNode:getPositionX();
    local y = starNode:getPositionY() - offsetY;
    starNode:setPosition(cc.p(x, y));

    -- 重绘按钮
    local btnBack = findChildByName(self.node, "BT/btn_back");
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));

    local btnOk = findChildByName(self.node, "CT/btn_ok");
    TextStyleM.setTextStyle(btnOk, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnOk:setTitleText(getLocStr("btn_text_ok"));
    btnOk:setVisible(false);

    -- 重绘选中的技能信息
    self:redrawSelectSkill();

    -- 显示当前探索点
    local spNode = findChildByName(self.node, "BT/sp_node");
    local iconImg = findChildByName(spNode, "icon");
    local icon = FieldsM.query("search_point", "icon");
    iconImg:loadTexture(getSmallAttribIconPath(icon));
    local amountLabel = findChildByName(spNode, "amount");
    TextStyleM.setTextStyle(amountLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BRIGHT_YELLOW, true);
    amountLabel:setString(tonumber(ME.user:queryAttrib("search_point")));
end

-- 重绘选中的技能信息
function UISkillInfo:redrawSelectSkill()

    local careerId = self.careerId;
    local careerInfo = CareerM.getCareerInfo(self.careerId);

    local isShowValue = CareerM.hasLearnedCareer(self.careerId);

    -- 显示bar中的职业名称和星级
    local careerNameLabel = findChildByName(self.node, "CT/bar/skill_name");
    TextStyleM.setTextStyle(careerNameLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, -2);
    careerNameLabel:setString(getLocStr("career_effect"));

    local content = "";

    local str = self:calcTotalBonus();

    content = content .. str;

    local propLabel = findChildByName(self.node, "CT/prop_node/all_props_desc");
    local descPositionY = propLabel:getPositionY();
    local descPositionX = propLabel:getPositionX();
    propLabel:setVisible(true);
    if isShowValue then
        -- 显示属性描述
        TextStyleM.setTextStyle(propLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_DARK_BROWN);
        local propStr = CareerM.getFeatureDesc(self.pet.classId, careerId, true, true);
        if string.len(content) > 0 and string.len(propStr) > 0 then
            content = content .. "\n" .. propStr;
        elseif string.len(propStr) > 0 then
            content = content .. propStr;
        end
    else
        TextStyleM.setTextStyle(propLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_GRAY);
        content = getLocStr("havent_learned_skill_tip");
    end

    -- 居中显示
    propLabel = applyString(propLabel, content);
    propLabel:setAnchorPoint(0.5, 0.5);
    propLabel:setPosition(descPositionX, descPositionY - 60);

    local careerBg = findChildByName(self.node, "CT/bg_icon");
    careerBg:setPosition(careerBg:getPositionX(), careerBg:getPositionY() - 80);

    local propNode = findChildByName(self.node, "CT/base_prop_node");
    propNode:setPosition(propNode:getPositionX(), propNode:getPositionY() - 30);

    -- 获取基础属性值
    local baseProps = CareerM.getFeatureBaseProps(self.pet.classId, careerId, false, true, true);
    local function getPropValue(field)
        for _, arr in pairs(baseProps) do
            if arr[2] == field then
                return arr[3];
            end
        end
        return 0;
    end

    -- 显示属性
    local function showAttribValue(value, valueLabel, nameLabel, parentNode, effectNode)
        TextStyleM.setTextStyle(nameLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BEIGE, false, -3);
        TextStyleM.setTextStyle(valueLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BEIGE, false, -3);
        if value <= 0 then
            -- 半透明显示
            valueLabel:setString("");
            parentNode:setOpacity(ATTRIB_OPACITY_VALUE);
            effectNode:setVisible(false);
        else
            valueLabel:setString("+" .. value);
            parentNode:setOpacity(255);

            -- 播放闪光特性
            effectNode:setVisible(true);
        end
    end

    -- 显示基础属性
    local basePropNode = findChildByName(self.node, "CT/base_prop_node");

    -- 攻击
    local attackNode = findChildByName(basePropNode, "attack_node");
    local nameLabel  = findChildByName(basePropNode, "attack_node/name");
    local valueLabel = findChildByName(basePropNode, "attack_node/value");
    local effectNode = findChildByName(basePropNode, "attack_node/effect_node");
    nameLabel:setString(getLocStr("attack"));
    local value = getPropValue("attack");

    if not isShowValue then
        value = 0;
    end
    showAttribValue(value, valueLabel, nameLabel, attackNode, effectNode);

    -- 生命
    local hpNode = findChildByName(basePropNode, "hp_node");
    nameLabel  = findChildByName(basePropNode, "hp_node/name");
    valueLabel = findChildByName(basePropNode, "hp_node/value");
    effectNode = findChildByName(basePropNode, "hp_node/effect_node");
    nameLabel:setString(getLocStr("hp"));
    local value = getPropValue("max_hp");

    if not isShowValue then
        value = 0;
    end
    showAttribValue(value, valueLabel, nameLabel, hpNode, effectNode);

    -- 魔力
    local magicNode = findChildByName(basePropNode, "magic_node");
    nameLabel  = findChildByName(basePropNode, "magic_node/name");
    valueLabel = findChildByName(basePropNode, "magic_node/value");
    effectNode = findChildByName(basePropNode, "magic_node/effect_node");
    nameLabel:setString(getLocStr("magic"));
    local value = getPropValue("magic");

    if not isShowValue then
        value = 0;
    end

    showAttribValue(value, valueLabel, nameLabel, magicNode, effectNode);

    -- 魔法
    local mpNode = findChildByName(basePropNode, "mp_node");
    nameLabel  = findChildByName(basePropNode, "mp_node/name");
    valueLabel = findChildByName(basePropNode, "mp_node/value");
    effectNode = findChildByName(basePropNode, "mp_node/effect_node");
    nameLabel:setString(getLocStr("mp"));
    local value = getPropValue("max_mp");

    if not CareerM.hasLearnedCareer(self.careerId) then
        value = 0;
    end

    showAttribValue(value, valueLabel, nameLabel, mpNode, effectNode);

    -- 显示背景称号图标
    -- 放放、半透明显示
    local bgIconImg = findChildByName(self.node, "CT/bg_icon");
    bgIconImg:loadTexture(getCareerIconPath(careerInfo["icon"]));
    bgIconImg:setScale(1.8);
    bgIconImg:setOpacity(50);
end

-- 注册点击事件
function UISkillInfo:registerTouchEvent()
    -- 注册返回按钮点击事件
    local btnBack = findChildByName(self.node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 关闭当前界面
            AudioM.playFx("button_return");
            UIMgr.getCurrentScene():removeFormByName("UISkillInfo");
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);

    -- 注册学习按钮点击事件
    local btnOk = findChildByName(self.node, "CT/btn_ok");
    local function onOkClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_click");
            UIMgr.getCurrentScene():removeFormByName("UISkillInfo");
        end
    end
    AddTouchEventListener(btnOk, onOkClick);
end

-- 计算奖励总数
function UISkillInfo:calcTotalBonus()

    local info = CareerM.getCareerInfo(self.careerId);
    local maxLevel = info["max_level"];

    local data = {
        ["level"] = 1,
        ["feature"] = {},
     };

    -- 刚学习的特性
    local ret1;
    local ret = {};
    for index = 1, 3 do
        local featureinfo = CareerM.getCareerInfo(self.careerId, "feature" .. index);
        if featureinfo and featureinfo["auto"] == 1 then
            -- 奖励
            ret1 = self:calcBonus(ME.user, featureinfo["bonus"], 1);
            ret = table.append(ret, ret1);
            data["feature"][index] = 1;
        end
    end

    -- 学习时奖励
    local ret2 = self:calcBonus(ME.user, info["base_bonus"], 1);

    ret = table.append(ret, ret2);

    -- 升级时的奖励
    for level = 2, maxLevel do
        local bonus;
        -- 找一个未满级的自动学习特性
        for index = 1, 3 do
            local featureInfo = info["feature" .. index] or {};
            local curLevel = data["feature"][index] or 0;
            local maxLevel = featureInfo["max_level"] or 0;
            if curLevel < maxLevel then
                data["feature"][index] = curLevel + 1;

                -- 奖励
                if featureInfo["bonus"] then
                    bonus = featureInfo["bonus"];
                    local ret3 = self:calcBonus(ME.user, bonus, level);
                    ret = table.append(ret, ret3);
                end

                break;
            end
        end
    end

    -- 逐个执行奖励
    local bonusAmount = 0;
    local bonusTypes = {};
    local str = "";
    local str1 = getLocStr("career_total_bonus1");
    local str2 = getLocStr("career_total_bonus2");

    -- 有相同的奖励合并，返回true，没有返回false
    local function isSameBonus(t, element)
        for _, bonus in pairs(t) do
            if bonus[2] == element[2] then
                bonus[3] = element[3] + bonus[3];
                return true;
            end
        end
        return false;
    end

    -- 计算奖励的类型，合并相同类型奖励
    for _, bonus in pairs(ret) do
        if #bonusTypes < 1 or isSameBonus(bonusTypes, bonus) ~= true then
            table.insert(bonusTypes, bonus);
        end
    end

    -- 特定描述
    local desc = CareerM.getCareerInfo(self.careerId, "desc");
    -- 特殊称号直接返回特定描述(异界游侠等有两种效果的)
    if table.indexOf({215, 216, 219, 220}, self.careerId) ~= -1 then
        return desc;
    end

    -- 编辑文本
    for i = 1, #bonusTypes do
        local bonus = bonusTypes[i];
        local name = "";
        if string.len(str) > 0 then
            str = str .. "\n";
        end
        if bonus[1] == 1 then
            if  type(bonus[2]) == "string" then
                str = str .. string.format(desc, bonus[3]);
            else
                name = ItemM.query(bonus[2], "name");
                -- 有特定描述的直接取，否则读取默认描述
                if desc and desc ~= "" then
                    if self.careerId ~= 21 then
                        str = str .. string.format(desc, bonus[3], name);
                    end
                else
                    if ITEM_TYPE_SPELL == ItemM.query(bonus[2], "type") then
                        str = str .. string.format(str1, bonus[3], name);
                    else
                        str = str .. string.format(str2, bonus[3], name);
                    end
                end
            end
        else
            name = FieldsM.getFieldName(bonus[2]);
            if self.careerId ~= 17 and self.careerId ~= 21 then
                str = str .. string.format(desc, bonus[3], name);
            else
                str = desc;
            end
        end
    end

    return str;
end

-- 计算奖励
function UISkillInfo:calcBonus(user, bonus, level)
    local arr;
    local id;
    local ret = {};

    -- 不符合奖励格式
    if not bonus or #bonus < 3 then
        return ret;
    end

    -- 奖励数量
    local count;
    if type(bonus[3]) == "table" then
        count = bonus[3][level];
    else
        count = bonus[3];
    end

    -- 一次性属性百分比提升
    if bonus[1] == 2 and #bonus == 4 then
        count = math.modf(user:queryAttrib(bonus[2]) * bonus[3] / 1000);
        -- 剑圣，加攻击时不计算某些buff影响
        if bonus[2] == "attack" then
            -- 清空所有buff、debuff、special
            local attrib = InterfaceM.calcBaseAttrib(user, "attack");

            count = math.modf(attrib * bonus[3] / 1000);
        end
        -- 光辉圣骑士，加最大生命需要先将生命值补满
        if bonus[2] == "max_hp" and
            user:queryAttrib("max_hp") - user:queryAttrib("hp") > 0 then
            table.insert(ret, {bonus[1], "hp", user:queryAttrib("max_hp") - user:queryAttrib("hp")});
        end
    end

    -- 奖励列表
    if type(bonus[2]) == "number" or bonus[1] == 2 then
        -- 属性奖励或正常物品奖励
        table.insert(ret, {bonus[1], bonus[2], count});
    elseif type(bonus[2]) == "table" then
        -- 称号等级不同奖励不同道具
        local itemInfo = bonus[2];
        if type(itemInfo[level]) == "number" then
            table.insert(ret, {bonus[1], itemInfo[level], count});
        end
    elseif type(bonus[2]) == "string" then
        arr = string.explode(bonus[2], ",");
        if bonus[2] == "piece" then
            -- 当前迷宫冈布奥碎片
            local dungeonId = DungeonM.getDungeonId();
            dungeonId = DungeonAreaM.getParentId(dungeonId);
            local slimeInfo = DungeonAreaM.getAreaSlime(dungeonId);
            if type(slimeInfo) == 'table' and #table.keys(slimeInfo) > 0 then
                id = table.values(slimeInfo)[1];
            else
                id = 1;
            end

            id = PetM.query(id, "chips");
        elseif bonus[2] == "random_piece" then
            id = "random_piece";
        elseif #arr > 1 then
            -- 奖励的食材，取当前拥有数量最少的
            id    = arr[1];
            id = "item," .. id;
        else
            -- 随机class_id范围奖励
            arr = string.explode(bonus[2], "~");
            id    = arr[1];
            id = "item," .. id;
        end

        -- 加入奖励列表
        table.insert(ret, {bonus[1], id, count});
    end

    return ret;
end